const KEY = '__XUANXIAOQIAN__'

export const $ = (text: string) => {
  return document.querySelector(`[${text}]`)
}

export const $loopWithDelay = async (callback: Function, delay: number, count = -1) => {
  if (count === -1) {
    let i = 0
    while (true) {
      if (callback) {
        const shouldBreak = await callback(i)
        if (shouldBreak === true) {
          break
        }
      }

      await new Promise(resolve => setTimeout(resolve, delay))
      i++
    }
  } else {
    for (let i = 0; i < count; i++) {
      if (callback) {
        const shouldBreak = await callback(i)
        if (shouldBreak === true) {
          break
        }
      }
      await new Promise(resolve => setTimeout(resolve, delay))
    }
  }
}


export const $setInput = (el: Element, text: string): void => {
  if (!['INPUT', 'TEXTAREA'].includes(el.tagName)) {
    const changeReactInputValue = (inputDom: Element, newText: string): void => {
      const lastValue = inputDom.textContent
      inputDom.textContent = newText
      const event = new Event('input', { bubbles: true })
        ; (event as any).simulated = true
      const tracker = (inputDom as any)._valueTracker
      if (tracker) {
        tracker.setValue(lastValue)
      }
      inputDom.dispatchEvent(event)
    }

    changeReactInputValue(el, text)
  } else {
    const changeReactInputValue = (inputDom: HTMLInputElement | HTMLTextAreaElement, newText: string): void => {
      const lastValue = inputDom.value
      inputDom.value = newText
      const event = new Event('input', { bubbles: true })
        ; (event as any).simulated = true
      const tracker = (inputDom as any)._valueTracker
      if (tracker) {
        tracker.setValue(lastValue)
      }
      inputDom.dispatchEvent(event)
    }
    changeReactInputValue(el as HTMLInputElement | HTMLTextAreaElement, text)
  }
}

// 原来的click不管用了可以用这个 type = mouseover || click
export const $click = (el: Element, type: string = 'mouseover') => {
  el.dispatchEvent(new MouseEvent(type, {
    'view': window,
    'bubbles': true,
    'cancelable': true
  }))
}


export const $createEl = <T extends object>(
  tagName: keyof HTMLElementTagNameMap,
  objAssign: Partial<T> = {} as T
): HTMLElement & T => {
  return Object.assign(document.createElement(tagName), objAssign) as HTMLElement & T
}

export const $setLocal = (key: string, value: unknown): boolean => {
  if (typeof key !== 'string') {
    console.error('[localStorage] Key must be a string')
    return false
  }

  let storageValue: string

  switch (typeof value) {
    case 'string':
      storageValue = value // 字符串直接存储（避免二次转义）
      break
    case 'undefined':
    case 'function':
    case 'symbol':
      console.warn(`[localStorage] Cannot store ${typeof value} type`)
      return false
    default:
      try {
        storageValue = JSON.stringify(value)
      } catch (e) {
        console.error('[localStorage] Stringify failed:', e)
        return false
      }
  }

  try {
    localStorage.setItem(`${KEY}__${key}`, storageValue)
    return true
  } catch (e) {
    console.error('[localStorage] Storage failed:', e)
    return false
  }
}



export const $getLocal = (key: string): unknown | null => {
  try {
    const item = localStorage.getItem(`${KEY}__${key}`)
    return item ? JSON.parse(item) : null
  } catch (e) {
    console.error(`[localStorage] Parse failed for key "${key}":`, e)
    return null
  }
}


// 往粘贴板添加内容
export const $setPaste = async (text: string): Promise<boolean | Error> => {
  try {
    if (!navigator.clipboard) {
      throw new Error('Clipboard API not available')
    }

    await navigator.clipboard.writeText(text)
    return true
  } catch (err) {
    return err instanceof Error ? err : new Error(String(err))
  }
}


export const scrollLi = async (el: Element) => {
  await nextTick()
  el.scrollTop = el.scrollHeight
}